package com.yand.thinkingInJava.thinkingInJava21.threadNewcomponent;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

class CheckoutTask<T> implements Runnable{

    private static int counter = 0;

    private int id = counter ++;

    private Pool<T> pool;

    public CheckoutTask(Pool<T> pool){
        this.pool = pool;
    }

    @Override
    public void run() {
       try{
           T item = pool.checkOut();
           System.out.println(this + "checked out "  + item);
           TimeUnit.SECONDS.sleep(1);
           System.out.println(item);
           pool.checkIn(item);


       } catch (InterruptedException e){

       }



    }

    public String toString(){

        return "CheckoutTask "+id+"";
    }

}


/**
 * Semaphore 信号计数量  初始化设定信号量
 * acquire 消耗信号量
 * release 释放信号量
 */
public class SemaphoreDemo {
    final static int SIZE = 25;
    public static  void main(String [] args) throws InterruptedException {
        final Pool<Fat> pool = new Pool<>(Fat.class, SIZE);
        ExecutorService exec = Executors.newCachedThreadPool();
        for(int i  =0 ; i < SIZE; i ++){
            exec.execute(new CheckoutTask<Fat>(pool));
        }
        System.out.println("All CheckoutTasks created");
        List<Fat> list = new ArrayList<>();
        for(int i  =0 ; i < SIZE; i++){
            Fat f = pool.checkOut();
            System.out.println(i + ": main() thread checked out ");
            f.operation();
            list.add(f);
        }

        Future<?> blocked = exec.submit(new Runnable() {

            @Override
            public void run() {
                try{

                    pool.checkOut();

                }catch (InterruptedException e){
                    System.out.println("checkOut() Interrupted");
                }


            }
        });


        TimeUnit.SECONDS.sleep(2);
        blocked.cancel(true);
        System.out.println("Checking in objects in "+ list);
        for(Fat f : list){
            pool.checkIn(f);
        }
        for(Fat f : list){
            pool.checkIn(f);
        }

        exec.shutdown();

    }

}
